package com.server.questionbank.snframe.config.filter;

import java.io.IOException;
import java.util.Set;

import com.server.questionbank.snframe.config.interceptor.JwtInterceptor;
import com.server.questionbank.snframe.util.JWT.JwtTokenProvider;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

/** 动态配置跨域，允许外部请求进行增加, asyncSupported 异步请求 */
@WebFilter(urlPatterns = "/*", asyncSupported = true)
@Slf4j
public class LsnCorsFilter implements Filter {

    @Value("${spring.security.allowed-origins:}")
    String[] allowedOrigins;
    @Autowired
    AllowedOrigninsBean corsOrignins;
    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
        if (allowedOrigins != null) {
            corsOrignins.addInBatch(allowedOrigins);
        }
    }

    private boolean isInList(String origin) {
        if (corsOrignins != null) {
            Set<String> oriList = corsOrignins.getOrignin();
            if (oriList != null) {
                if (oriList.contains(origin)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 设置当前线程的JwtTokenProvider
        JwtInterceptor.jwtTokenProvider = jwtTokenProvider;

        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;


        // 获取客户端真实IP 并 设置到JwtInterceptor中
        JwtInterceptor.setCurrentIp(getClientIp(req));
        JwtInterceptor.setCurrentUser(req);

        // 获取请求的源（Origin）
        String origin = req.getHeader("Origin");
        String originPrefix = req.getScheme() + "://" + req.getRemoteHost();
        boolean isAllowed = false;
        if (origin == null) {
            origin = originPrefix + ":" + req.getRemotePort();
            isAllowed = isInList(origin);
        } else {
            isAllowed = isInList(origin);
        }
        if (false == isAllowed) {
            isAllowed = isInList(originPrefix);
            if (false == isAllowed) log.warn("来自【{}】的跨域访问被拦截", origin);
        }
        // 检查请求的源是否为允许的源
        if (isAllowed) {
            // 设置CORS头
            res.setHeader("Access-Control-Allow-Origin", origin);
            // res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE,
            // OPTIONS");
            res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS,DELETE");
            // res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization,
            // X-Requested-With");
            res.setHeader("Access-Control-Allow-Headers", "*");
            res.setHeader("Access-Control-Allow-Credentials", "true");
            res.setHeader("access-control-max-age", "3600");

            // 对于预检请求（OPTIONS），直接返回响应，不继续链中的其他过滤器或目标资源
            if ("OPTIONS".equalsIgnoreCase(req.getMethod())) {
                res.setStatus(HttpServletResponse.SC_OK);
                return;
            }
        }
        // 继续链中的其他过滤器或目标资源
        chain.doFilter(request, response);
    }

    /**
     * 获取客户端真实IP
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        // 如果有多个 IP 地址，以逗号分隔，取第一个
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            String[] ips = ip.split(",");
            return ips[0].trim();  // 取第一个 IP
        }

        // 如果没有 X-Forwarded-For 或其值无效，回退到 Proxy-Client-IP
        ip = request.getHeader("Proxy-Client-IP");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }

        // 如果没有 Proxy-Client-IP，回退到 WL-Proxy-Client-IP
        ip = request.getHeader("WL-Proxy-Client-IP");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }

        // 如果都没有，再回退到 getRemoteAddr()
        ip = request.getRemoteAddr();
        return ip;
    }

    @Override
    public void destroy() {
        // 销毁过滤器（如果需要）
    }
}
